<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\Common\Robot\Robot;
use App\CustHub\Mapper\ChCorpMapper;
use App\CustHub\Mapper\ChRobotMapper;
use App\CustHub\Model\ChCorp;
use App\Robot\Service\RobotApiService;
use FriendsOfHyperf\Lock\Exception\LockTimeoutException;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Hyperf\Di\Annotation\Inject;
use Mine\Abstracts\AbstractService;
use Mine\Exception\NormalStatusException;
use Mine\MineModel;
use function FriendsOfHyperf\Lock\lock;
use function Hyperf\Support\optional;

class ChCorpService extends AbstractService
{
    public $mapper;

    #[Inject]
    protected ChRobotMapper $robotMapper;

    /**
     * @var mixed|string
     */

    public function __construct(ChCorpMapper $mapper)
    {
        $this->mapper = $mapper;
    }


    public function getSelectList(array $params)
    {
        $list = ChCorp::query()
            ->select(['id', 'corp_id', 'corp_name', 'corp_full_name'])
            ->where('main_uid', $params['main_uid'])
            ->where('type', 0)
            ->when(!empty($params['keyword']), function ($query) use ($params) {
                $query->where('corp_name', 'like', '%' . $params['keyword'] . '%');
            })
            ->get()->toArray();
        return $list;
    }

    /**
     * 修改企业的corp_name和corp_id信息
     * @param int $corpId id
     * @param array $newData 包含新的corp_name和corp_id的数组，格式如 ['corp_name' => '新名称', 'corp_id' => '新ID']
     * @return bool 修改成功返回true，失败返回false
     */
    public function updateCorp($corpId, array $newData)
    {
        $result = ChCorp::query()
            ->where('id', $corpId)
            ->update($newData);
        return $result > 0;
    }

    /**
     * 根据企业ID同步企业信息
     * @param mixed $robotId
     * @param mixed $corpId
     * @return MineModel|Model|bool|string|ChCorp|Builder|null
     */
    public function syncCorpDataByCorpId(mixed $robotId, mixed $corpId, int $mainUid): \Mine\MineModel|Model|bool|string|ChCorp|Builder|null
    {
        $lock = lock('sync_corp_info_lock' . $corpId . '_' . $mainUid, 4);
        try {
            $lock->block(2);
            $model = $this->mapper->findByCorpId($corpId, $mainUid);
            if (empty($model)) {
                $robotInfo = $this->robotMapper->findById($robotId);
                $robotApiService = make(Robot::class, [$robotInfo->server_id, $robotInfo->uuid])->gateway();
                $response = $robotApiService->getCorpInfo([$corpId]);
                if ($response !== false) {
                    $corpList = $response['corp_list'];
                    $corpInfo = array_shift($corpList);

                    $exitsCorpInfo = $this->mapper->findByCorpName($corpInfo['corp_name'], $mainUid);
                    if ($exitsCorpInfo) {
                        $this->mapper->update($exitsCorpInfo['id'], [
                            'corp_id' => $corpId,
                            'corp_admin_id' => $corpInfo['corp_admin_id'],
                            'corp_owner_name' => $corpInfo['corp_owner_name'],
                            'corp_create_time' => $corpInfo['corp_create_time'],
                        ]);
                    } else {
                        $corpInfo['uid'] = $robotInfo['uid'];
                        $corpInfo['main_uid'] = $robotInfo['main_uid'];
                        $this->mapper->filterExecuteAttributes($corpInfo, $this->mapper->getModel()->incrementing);
                        $model = $this->mapper->model::create($corpInfo);
                    }
                    $this->mapper->clearCacheByCorpId($corpId, $mainUid);
                }
            }
            return $model;
        } catch (LockTimeoutException $e) {
            // 无法获取锁...
            return null;
        } finally {
            optional($lock)->release();
        }
    }

    /**
     * 删除企业
     * @param mixed $id
     * @return bool|int|mixed|null
     * @throws \Exception
     */
    public function deleteCorp(mixed $id)
    {
        $count = $this->robotMapper->model::query()
            ->where('corp_id', $id)
            ->count();

        if ($count > 0) {
            throw new NormalStatusException('请先删除该企业下的企微号');
        }

        return $this->mapper->model::query()
            ->where('id', $id)
            ->delete();
    }
}